/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

import net from 'net';

import { DAEMON_SERVER_LOCAL_HOST, DAEMON_SERVER_MAX_LISTEN_PORT } from '../const/daemon-const.js';
import { HvigorDaemonLogger } from '../log/hvigor-daemon-log.js';
import { defaultDaemonServerRegistry } from '../registry/daemon-server-registry.js';

const log = HvigorDaemonLogger.getLogger('daemon');

function isPortInUsed(port: number) {
  return new Promise((resolve) => {
    const server = net.createServer().listen(port, DAEMON_SERVER_LOCAL_HOST);
    server.on('listening', function () {
      server.close();
      resolve(port);
    });
    server.on('error', function (err: Error) {
      resolve(err);
    });
  });
}

export async function tryUsePort(port: number): Promise<number> {
  const getRegistryPortInUsed = defaultDaemonServerRegistry.getAllPortInUsed();

  // 已经在注册表中被使用的port不用尝试连接,直接+1
  while (getRegistryPortInUsed.includes(port)) {
    log.debug(`${port} is occupied by hvigor daemon.`);

    port++;

    // 超过设置的最大端口号范围,直接返回-1
    if (port > DAEMON_SERVER_MAX_LISTEN_PORT) {
      return -1;
    }
  }

  // 判断端口是否有被其他进程占用
  const checkResult = await isPortInUsed(port);
  if (checkResult instanceof Error) {
    log.debug(`${port} is occupied by other process.`);

    port++;

    // 超过设置的最大端口号范围,直接返回-1
    if (port > DAEMON_SERVER_MAX_LISTEN_PORT) {
      return -1;
    }
    return tryUsePort(port);
  } else {
    return port;
  }
}
